using System.Reflection;

namespace Guia.Config
{
    using System;
    using System.Configuration;
    using System.Resources;
    using Guia.Core;

    /// <summary>
    /// Implementation of the IConfig interface using the .NET ApplicationConfiguration (app.config).
    /// </summary>
    public class AppConfigImpl : IConfig
    {
        /// <summary>
        /// Lock object.
        /// </summary>
        private static readonly object LockObject = new object();

        /// <summary>
        /// Reference to the AppConfig
        /// </summary>
        private readonly Configuration configuration;

        /// <summary>
        /// Instance of the class.
        /// </summary>
        private static AppConfigImpl instance;

        /// <summary>
        /// Prevents a default instance of the <see cref="AppConfigImpl"/> class from being created.
        /// </summary>
        private AppConfigImpl()
        {
            this.configuration = ConfigurationManager.OpenExeConfiguration("Guia.dll");

            // if no configuration file was found, try to load it explicitely from the assembly location.
            if (!this.configuration.HasFile)
            {
                string dllPath = Assembly.GetExecutingAssembly().Location;
                dllPath = dllPath.Substring(0, dllPath.LastIndexOf("\\") + 1);
                this.configuration = ConfigurationManager.OpenExeConfiguration(dllPath + "Guia.dll");
                if (!this.configuration.HasFile)
                {
                    throw new GuiaException("Could not load Guia configuration. Please make sure, \"" + dllPath + "Guia.dll.config\" exists. You may adapt the deployment for your project, so that this file is copied together with \"Guia.dll\".");
                }
            }
        }

        /// <summary>
        /// Gets the instance.
        /// </summary>
        public static AppConfigImpl Instance
        {
            get
            {
                lock (LockObject)
                {
                    if (instance == null)
                    {
                        instance = new AppConfigImpl();
                    }

                    return instance;
                }
            }
        }

        #region IConfig Members

        /// <summary>
        /// Gets the timeout for the element search
        /// </summary>
        public int ElementTimeout
        {
            get
            {
                string timeString = this.configuration.AppSettings.Settings["AutomationElementFinderTimeout"].Value;
                return Convert.ToInt32(timeString);
            }
        }

        /// <summary>
        /// Gets the timeout for the window search
        /// </summary>
        public int WindowTimeout
        {
            get
            {
                string timeString = this.configuration.AppSettings.Settings["WindowFinderTimeout"].Value;
                return Convert.ToInt32(timeString);
            }
        }

        /// <summary>
        /// Gets the timeout for the closing of modal windows.
        /// </summary>
        public int CloseModalWindowsTimeout
        {
            get
            {
                string timeString = this.configuration.AppSettings.Settings["CloseModalWindowsTimeout"].Value;
                return Convert.ToInt32(timeString);
            }
        }

        /// <summary>
        /// Gets the localized name of an element
        /// </summary>
        /// <param name="element">The element wanted</param>
        /// <returns>The localized name of the given element</returns>
        public string GetLocalizedName(EElementIdentifier element)
        {
            return LocalStrings.ResourceManager.GetString(element.ToString());
        }

        #endregion
    }
}